﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ArchiSimple.Windows.Model;
using System.Windows;
using System.Reflection;
#if NETFX_CORE
using Windows.UI;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
#else
using System.Windows.Media;
#endif
using ArchiSimple.Windows.Tools;
using System.Collections.ObjectModel;

namespace ArchiSimple.Windows.ViewModel.PlanObjects
{
    public class RoomViewModel : PlanObjectViewModel<Room>
    {
        public class SelectColor
        {
            public Color Color { get; set; }

            public string Name { get; set; }
        }

        public RoomViewModel(PlanViewModel plan, Room model, Designer designer)
            : base(plan, model, designer)
        {
            foreach (var point in this.Current.Points)
            {
                var vm = this.Plan.CreateOrGet(point) as PointViewModel;
                vm.Notify(p => p.X, RefreshGeometry);
                vm.Notify(p => p.Y, RefreshGeometry);
            }

            RefreshGeometry();
        }

        private void RefreshGeometry()
        {
            double minX = double.MaxValue;
            double maxX = 0;
            double minY = double.MaxValue;
            double maxY = 0;

            var points = this.Current.Points;

            for (int i = 0; i < points.Count; i++)
            {
                this.Designer.SetPoint(this.zoneFigure, i, points[i]);

                double x = points[i].X;
                double y = points[i].Y;

                if (x < minX)
                {
                    minX = x;
                }

                if (x > maxX)
                {
                    maxX = x;
                }

                if (y < minY)
                {
                    minY = y;
                }

                if (y > maxY)
                {
                    maxY = y;
                }
            }

            if (this.Zone == null)
            {
                this.Zone = new Rectangle
                {
                    X = minX,
                    Y = minY,
                    Width = maxX - minX,
                    Height = maxY - minY,
                };
            }
            else
            {
                var zone = this.Zone;
                zone.X = minX;
                zone.Y = minY;
                zone.Width = maxX - minX;
                zone.Height = maxY - minY;
            }
        }

        public string Title
        {
            get { return this.Current.Title; }
            set
            {
                this.Current.Title = value;
                RaisePropertyChanged(() => Title);
            }
        }

        public Color Color
        {
            get { return this.Current.Color; }
            set
            {
                this.Current.Color = value;
                RaisePropertyChanged(() => Color);
            }
        }

        public ObservableCollection<SelectColor> ColorsAllowed
        {
            get
            {
                var q = from c in typeof(Colors).GetProperties()
                        where c.PropertyType == typeof(Color)
                        select new SelectColor
                        {
                            Color = (Color)c.GetValue(null, new object[0]),
                            Name = c.Name,
                        };

                return q.ToObservable();
            }
        }

        private PathFigure zoneFigure = null;

        public PathGeometry ZoneGeometry
        {
            get
            {
                var geo = new PathGeometry();
                if (this.zoneFigure == null)
                {
                    this.zoneFigure = this.Designer.MakePath(this.Current.Points);
                }

                geo.Figures.Add(this.zoneFigure);
                return geo;
            }
        }

        public override PathGeometry SelectedGeometry
        {
            get { return this.ZoneGeometry; }
        }

        public PointViewModel[] Points
        {
            get
            {
                return (from p in this.Current.Points
                        select this.Plan.CreateOrGet(p)).Cast<PointViewModel>().ToArray();
            }
        }

        public void InsertPointAfter(int index, PointViewModel point)
        {
            point.Notify(p => p.X, RefreshGeometry);
            point.Notify(p => p.Y, RefreshGeometry);

            this.Current.Points.Insert(index, point.Current);
            this.zoneFigure = null;
            RefreshGeometry();
            RaisePropertyChanged(() => Points);
            RaisePropertyChanged(() => ZoneGeometry);
            RaisePropertyChanged(() => SelectedGeometry);
        }

        public override void Delete()
        {
            this.Plan.RemoveFromPlan(this);
        }
    }
}
